package org.fastsyncer.server.jetty;

import java.awt.Desktop;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLDecoder;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.Properties;
import java.util.ResourceBundle;

import org.fastsyncer.common.util.ApplicationUtil;
import org.fastsyncer.manager.increment.IncrementFactory;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.webapp.WebAppClassLoader;
import org.mortbay.jetty.webapp.WebAppContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public final class JettyServer {

	private static Logger logger = LoggerFactory.getLogger(JettyServer.class);
	private static Server server;

	static {
		// 加载默认配置文件（application.properties）
		ResourceBundle pro = ResourceBundle.getBundle("application");
		Enumeration<String> keys = pro.getKeys();
		while (keys.hasMoreElements()) {
			String key = (String) keys.nextElement();
			String value = pro.getString(key);
			System.setProperty(key, value);
		}

		ApplicationUtil.setKey(JettyServerEnum.PORT.getKey(), JettyServerEnum.PORT.getValue());
		ApplicationUtil.setKey(JettyServerEnum.CONTEXT.getKey(), JettyServerEnum.CONTEXT.getValue());
		ApplicationUtil.setKey(JettyServerEnum.WEB_PATH.getKey(), JettyServerEnum.WEB_PATH.getValue());
		ApplicationUtil.setKey(JettyServerEnum.ROOT.getKey(), JettyServerEnum.ROOT.getValue());
		ApplicationUtil.setKey(JettyServerEnum.ROOT_DESCRIPTOR.getKey(), JettyServerEnum.ROOT_DESCRIPTOR.getValue());
	}

	private JettyServer(String[] args) throws IOException {
		this.load(args);
		logger.info("args:" + Arrays.toString(args));
		logger.info("root:" + ApplicationUtil.getKey(JettyServerEnum.ROOT.getKey()));
		logger.info("root.descriptor:" + ApplicationUtil.getKey(JettyServerEnum.ROOT_DESCRIPTOR.getKey()));
	}

	/**
	 * 初始化配置信息
	 * 
	 * @param args
	 * @throws IOException
	 */
	private void load(String[] args) throws IOException {
		if (args != null && args.length > 0) {
			// C:\Users\Administrator\Desktop\fastsyncer-server-0.0.1-SNAPSHOT
			String currentPath = args[0];

			// 1.获取配置文件
			String proPath = currentPath + "/conf/boot/fastsyncer.properties";
			FileInputStream in = new FileInputStream(URLDecoder.decode(proPath, "utf-8"));
			Properties pro = new Properties();
			pro.load(in);
			for (@SuppressWarnings("rawtypes")
			Enumeration e = pro.propertyNames(); e.hasMoreElements();) {
				String key = (String) e.nextElement();
				// 覆盖写入
				ApplicationUtil.setKey(key, pro.getProperty(key));
			}
			in.close();

			// 替换web上下文配置
			ApplicationUtil.setKey(JettyServerEnum.ROOT.getKey(), JettyServerEnum.DEF_ROOT.getValue());
			ApplicationUtil.setKey(JettyServerEnum.ROOT_DESCRIPTOR.getKey(), JettyServerEnum.DEF_ROOT_DESC.getValue());
		}
	}

	private void start() {
		try {
			// 启动监听服务
			new IncrementFactory().start();
			
			// 服务器的监听端口
			server = new Server(Integer.parseInt(ApplicationUtil.getKey(JettyServerEnum.PORT.getKey())));
			// 创建一个新的上下文
			WebAppContext context = new WebAppContext();
			server.setHandler(context);

			this.reloadContext(server);
			server.start();
			
			// 打印帮助信息
			this.printHelpInfo();

			// 等待用户输入命令.
			while (true) {
				char c = (char) System.in.read();
				switch (c) {
				case 'h':
					this.printHelpInfo();
					break;
				case 'o':
					this.openBrowser();
					break;
				case 'r':
					this.reloadContext(server);
					break;
				case 'x':
					System.out.println("正在停止服务...");
					System.exit(-1);
					break;
				default:
					break;
				}
			}
		} catch (Exception e) {
			logger.error(e.getMessage(), e.getClass(), e.getCause());
		}
	}

	/**
	 * 快速重新启动application，重载classes
	 */
	private void reloadContext(Server server) throws Exception {
		WebAppContext context = (WebAppContext) server.getHandler();
		context.stop();
		// 设置上下文路径
		context.setContextPath(ApplicationUtil.getKey(JettyServerEnum.CONTEXT.getKey()));
		// 设置Web内容上下文路径
		context.setResourceBase(ApplicationUtil.getKey(JettyServerEnum.ROOT.getKey()));
		// 设置描述符位置
		context.setDescriptor(ApplicationUtil.getKey(JettyServerEnum.ROOT_DESCRIPTOR.getKey()));
		// 设置当前运行上下文
		context.setClassLoader(Thread.currentThread().getContextClassLoader());
		// 设置优先级
		context.setParentLoaderPriority(true);
		WebAppClassLoader classLoader = new WebAppClassLoader(context);
		context.setClassLoader(classLoader);
		context.start();
	}

	/**
	 * 打开浏览器
	 * 
	 * @throws URISyntaxException
	 * @throws IOException
	 */
	private void openBrowser() throws IOException, URISyntaxException {
		String _port = ApplicationUtil.getKey(JettyServerEnum.PORT.getKey());
		String _context = ApplicationUtil.getKey(JettyServerEnum.CONTEXT.getKey());
		Desktop.getDesktop().browse(new URI("http://localhost:" + _port + _context));
	}

	/**
	 * 打印帮助信息
	 */
	private void printHelpInfo() {
		System.out.println("> h\t显示帮助");
		System.out.println("> o\t打开首页");
		System.out.println("> r\t迅速重启");
		System.out.println("> x\t停止应用");
	}

	public static void main(String[] args) throws Exception {
		// 启用web服务
		new JettyServer(args).start();
	}

}